#include "logindialog.h"
#include "ui_logindialog.h"
#include "singleton.h"
#include "httpmgr.h"
#include "global.h"
#include "tcpmanager.h"

#include <QPixmap>
#include <QPainter>
#include <QPainterPath>
#include <QRegularExpression>
#include <QJsonDocument>

LoginDialog::LoginDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::LoginDialog)
{
    ui->setupUi(this);

    _SetConnect();
    _SetWidgetState();
    _SetImage();
    _InitHandlers();
}

void LoginDialog::_InitHandlers()
{
    _handlers.insert(ReqId::ID_LOGIN_USER, [this](const QJsonObject& json){

        int error = json["code"].toInt();
        if(error != ErrorCode::SUCCESS)
        {
            ui->login_button->setEnabled(true);
            _ShowTips(tr("json 参数错误"), false);
            qDebug() << "error message: " << json["msg"].toString();
            return;
        }

        ServerInfo info;
        info.Host = json["host"].toString();
        info.Id = json["id"].toInt();
        info.Port = json["port"].toString();
        info.Token = json["token"].toString();
        qDebug() << "host: " << info.Host << ", port: " << info.Port
                 << ", id: " << info.Id << ", token: " << info.Token;

        _id = info.Id;
        _token = info.Token;

        emit sigConnectTcp(info);
    });
}

void LoginDialog::_SetConnect()
{
    //注册按钮信号 - 发送自定义信号
    connect(ui->register_btn, &QPushButton::clicked, this, &LoginDialog::switchRegister);

    //忘记密码按钮信号
    connect(ui->forget_password_label, &ClickedLabel::clicked, this, &LoginDialog::slot_forget_pwd);

    //登录按钮槽函数发送信号到 TcpManager
    connect(this, &LoginDialog::sigConnectTcp, MagicSingleton<TcpManager>::GetInstance().get(), &TcpManager::slot_tcp_connect);

    //连接服务器信号
    connect(MagicSingleton<TcpManager>::GetInstance().get(), &TcpManager::sig_tcp_connect, this, &LoginDialog::_slot_tcp_connect);

    //登录错误信号
    connect(MagicSingleton<TcpManager>::GetInstance().get(), &TcpManager::sig_login_failed, this, &LoginDialog::_slot_login_faile);

    connect(ui->email_edit, &QLineEdit::editingFinished, this, [this](){
        this->_CheckInput();
    });
    connect(ui->pass_edit, &QLineEdit::editingFinished, this, [this](){
        this->_CheckInput();
    });

    connect(ui->login_label, &ClickedLabel::clicked, this, [this]() {
        auto state = ui->login_label->GetCurState();
        if(state == ClickLbState::Normal){
            ui->pass_edit->setEchoMode(QLineEdit::Password);
        }else{
            ui->pass_edit->setEchoMode(QLineEdit::Normal);
        }
        qDebug() << "Label was clicked!";
    });

    connect(MagicSingleton<HttpMgr>::GetInstance().get(),&HttpMgr::sig_login_mod_finish,
            this, &LoginDialog::_SlotLoginModFinish);
}

void LoginDialog::_SetWidgetState()
{
    ui->forget_password_label->SetState("normal","hover","","selected","selected_hover","");

    ui->login_label->SetState("unvisible","unvisible_hover","","visible",
                                  "visible_hover","");
}


void LoginDialog::_ShowTips(QString msg, bool flag)
{
    ui->head_label->clear();
    flag == true ? ui->head_label->setStyleSheet("color: green;") : ui->head_label->setStyleSheet("color: red;");
    ui->head_label->setText(msg);
}

bool LoginDialog::_CheckInput()
{
    if(ui->email_edit->text().isEmpty())
    {
        _ShowTips(tr("邮箱不能为空"), false);
        return false;
    }
    auto email = ui->email_edit->text();
    QRegularExpression regex(R"((\w+)(\.|_)?(\w*)(\.(\w+))+)");
    if(!regex.match(email).hasMatch())
    {
        _ShowTips(tr("邮箱格式不正确"), false);
        return false;
    }

    if(ui->pass_edit->text().isEmpty())
    {
        _ShowTips(tr("密码不能为空"), false);
        return false;
    }
    if(ui->pass_edit->text().size() < 6)
    {
        _ShowTips(tr("密码长度不能小于6位"), false);
        return false;
    }

    ui->head_label->clear();
    return true;
}

void LoginDialog::_SetImage()
{
    QPixmap img(":res/head_2.jpg");
    //设置头像图片大小自适应，平滑变换效果
    img = img.scaled(ui->img_label->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    //创建一个透明的画布，填充透明色
    QPixmap pixmap(ui->img_label->size());
    pixmap.fill(Qt::transparent);

    //绘制圆角矩形路径
    QPainterPath path;
    path.addRoundedRect(pixmap.rect(), 10, 10);
    //创建画笔，在透明画布上绘制图像
    QPainter painter(&pixmap);

    //抗锯齿效果，使圆角更平滑
    painter.setRenderHint(QPainter::Antialiasing);
    //设置裁剪路径，只绘制圆角矩形内的图像
    painter.setClipPath(path);
    //绘制图像到画布上
    painter.drawPixmap(0, 0, img);
    ui->img_label->setPixmap(pixmap);
}

void LoginDialog::slot_forget_pwd()
{
    emit switchReset();
}


LoginDialog::~LoginDialog()
{
    qDebug() << "~LoginDialog run";
    delete ui;
}

void LoginDialog::on_login_button_clicked()
{
    if(!_CheckInput())
    {
        return;
    }

    // 设置登录按钮不可用，防止重复点击
    ui->login_button->setEnabled(false);

    QJsonObject json_obj;
    json_obj["email"] = ui->email_edit->text();
    json_obj["password"] = ui->pass_edit->text();
    auto url = QUrl(gate_url_prefix + "/user_login");
    MagicSingleton<HttpMgr>::GetInstance()->PostHttpReq(url, json_obj, ReqId::ID_LOGIN_USER, Modules::LOGIN_MOD);
}

void LoginDialog::_SlotLoginModFinish(ReqId id, ErrorCode err, QString res)
{
    if(err != ErrorCode::SUCCESS)
    {
        _ShowTips(tr("网络请求错误"), false);
        return;
    }


    //解析 json
    QJsonDocument jsonDoc = QJsonDocument::fromJson(res.toUtf8());
    if(jsonDoc.isNull())
    {
        _ShowTips(tr("json 解析失败"), false);
        qDebug() << __FILE__ << ":" << __LINE__ << "  json 解析失败";
        return;
    }
    if(!jsonDoc.isObject())
    {
        _ShowTips(tr("json 解析错误"), false);
        qDebug() << __FILE__ << ":" << __LINE__ << "  json 解析错误";
        return;
    }

    //根据id回调指定的函数
    _handlers[id](jsonDoc.object());

    return;
}


void LoginDialog::_slot_tcp_connect(bool flag)
{
    if(!flag)
    {
        _ShowTips(tr("网络异常"), false);
        ui->login_button->setEnabled(true);
        return;
    }

    _ShowTips(tr("服务器连接成功，正在登录..."), true);
    QJsonObject json;
    json["token"] = _token;
    json["id"] = (int)_id;

    QJsonDocument doc(json);
    QString msg = doc.toJson(QJsonDocument::Indented);
    //发送登录信息
    MagicSingleton<TcpManager>::GetInstance()->sig_send_data(ReqId::ID_CHAT_LOGIN, msg);
}

void LoginDialog::_slot_login_faile(int code)
{
    QString msg = QString("登录失败，错误码：%1").arg(code);
    _ShowTips(msg, false);
    ui->login_button->setEnabled(true);
}
